import useManualTreeExpandControl from '@/hooks/useManualTreeExpandControl';
import ApiSystemUser from '@/services/system/ApiSystemUser';
import { FormItemProps } from '@/typing';
import { Input, Spin, Tree } from 'antd';
import React, { useEffect, useMemo, useState } from 'react';

const { Search } = Input;

const getParentKey = (key: React.Key, tree: any[]): React.Key => {
  let parentKey: React.Key;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some((item: { id: React.Key }) => item.id === key)) {
        parentKey = node.id;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey!;
};

const SystemDeptSearchTree: React.FC<FormItemProps> = (props) => {
  const expandControl = useManualTreeExpandControl({
    treeProps: { id: 'deptId' },
  });

  const [searchValue, setSearchValue] = useState('');

  const onExpand = (newExpandedKeys: React.Key[]) => {
    expandControl.onExpand(newExpandedKeys);
  };

  const onSearchChange = (value: string) => {
    const newExpandedKeys = expandControl.listData
      .map((item) => {
        if (item.label.indexOf(value) > -1) {
          return getParentKey(item.id, expandControl.treeData);
        }
        return null;
      })
      .filter(
        (item, i, self): item is React.Key =>
          !!(item && self.indexOf(item) === i),
      );
    setSearchValue(value);
    expandControl.onExpandAutoParent(newExpandedKeys);
  };

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    onSearchChange(value);
  };

  const treeData = useMemo(() => {
    const loop = (data: any[]): any[] =>
      data.map((item) => {
        const strTitle = item.label as string;
        const index = strTitle.indexOf(searchValue);
        const beforeStr = strTitle.substring(0, index);
        const afterStr = strTitle.slice(index + searchValue.length);
        const title =
          index > -1 ? (
            <span key={item.id}>
              {beforeStr}
              <span className="bg-amber-300">{searchValue}</span>
              {afterStr}
            </span>
          ) : (
            <span key={item.id}>{strTitle}</span>
          );
        if (item.children) {
          return { title, key: item.id, children: loop(item.children) };
        }

        return {
          title,
          key: item.key,
        };
      });

    let result = loop(expandControl.treeData);
    // 数据计算完成后, 触发一次展开节点
    onSearchChange(searchValue);
    return result;
  }, [searchValue, expandControl.treeData]);

  useEffect(() => {
    ApiSystemUser.deptTree({}).then((data: any[]) => {
      expandControl.cacheTreeData(data);
    });
  }, []);

  return (
    <div>
      <Search
        style={{ marginBottom: 8 }}
        placeholder="请输入部门名称"
        onChange={onChange}
      />
      <Spin
        spinning={!expandControl.listData || expandControl.listData.length < 1}
      >
        <Tree
          defaultExpandAll
          activeKey={props.value || 0}
          onExpand={onExpand}
          expandedKeys={expandControl.expandedKeys}
          autoExpandParent={expandControl.autoExpandParent}
          treeData={treeData}
          onSelect={(selectedKeys, info) => {
            const selectedDeptId = info?.node?.title?.key;
            props?.onChange?.(selectedDeptId || 0);
          }}
        />
      </Spin>
    </div>
  );
};

export default SystemDeptSearchTree;
